<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Upload Class - Usage - Fuel Documentation</title>
	<link href="../../assets/css/main.css" media="screen" rel="stylesheet" />
	<script type="text/javascript" src="../../assets/js/jquery-1.4.4.min.js"></script>
	<script type="text/javascript" src="../../assets/js/nav.js"></script>
	<script type="text/javascript" src="../../assets/js/highlight.pack.js"></script>
	<script type="text/javascript">
		$(function() {
			show_nav('classes', '../../');
		});
		hljs.tabReplace = '    ';
		hljs.initHighlightingOnLoad();
	</script>
</head>
<body>

	<header>
		<h1>Fuel Documentation</h1>
	</header>

	<div id="main-nav"></div>

	<section id="content">
		<h2>Upload Class</h2>

		<p>
			The upload class allows to securely process files that have been uploaded to the application.
			It allows you to filter uploads in various ways, define what the destination filenames should look like, or filter on size or length of the filename.
		</p>

		<h3>Uploaded files array</h3>

		<p>Information of every uploaded file is stored in a multidimensional array within the Upload class.
			For every file, an array is defined with the following fields:
		</p>

		<table class="config">
			<tbody>
				<tr class="header">
					<th>Key</th>
					<th>Type</th>
					<th>Description</th>
				</tr>
				<tr>
					<th>field</th>
					<td>string</td>
					<td>
						Name of the form field that was used to upload the file.
					</td>
				</tr>
				<tr>
					<th>key</th>
					<td>mixed</td>
					<td>
						If the form field was defined as an array, the key used. If not, this field is set to false.
					</td>
				</tr>
				<tr>
					<th>name</th>
					<td>string</td>
					<td>
						Name of the file uploaded.
					</td>
				</tr>
				<tr>
					<th>type</th>
					<td>string</td>
					<td>
						Mime-type of the file uploaded, as defined by the browser.
					</td>
				</tr>
				<tr>
					<th>mimetype</th>
					<td>string</td>
					<td>
						Mime-type of the file uploaded, as determined by the Upload class.
						Note that this requires an up-to-date 'mime magic' file to be installed.
						This file is present on every *nix platform, but on Windows platforms, you might have to install this file yourself.
						If the mime-type can not be determined, this field contains the same value as 'type'.
					</td>
				</tr>
				<tr>
					<th>file</th>
					<td>string</td>
					<td>
						The fully qualified filename of the temporary location of the uploaded file.
					</td>
				</tr>
				<tr>
					<th>filename</th>
					<td>string</td>
					<td>
						The filename (basename) of the file uploaded.
					</td>
				</tr>
				<tr>
					<th>extension</th>
					<td>string</td>
					<td>
						The extension of the file uploaded.
					</td>
				</tr>
				<tr>
					<th>size</th>
					<td>integer</td>
					<td>
						The size in bytes of the file uploaded.
					</td>
				</tr>
				<tr>
					<th>error</th>
					<td>integer</td>
					<td>
						The error detected when uploading the file or when validating the uploaded file. If zero, there were no errors.
					</td>
				</tr>
			</tbody>
		</table>

		<p>
			Note that mime-type will always contain the most specific type. So if the browser claims it's an MS-Word document, but the mime-type
			is determined as being "application/octet-stream", the browser's mime-type is used, even if this may be wrong or unexpected!
			For example, a Microsoft .xlsx file might be detected as being "application/zip".
		</p>

		<p>
			After you have called the save() method, this array structure is expanded with two extra fields, giving you information about what was actually saved.
		</p>

		<table class="config">
			<tbody>
				<tr class="header">
					<th>Key</th>
					<th>Type</th>
					<th>Description</th>
				</tr>
				<tr>
					<th>saved_to</th>
					<td>string</td>
					<td>
						Fully qualified path where the uploaded file was saved.
					</td>
				</tr>
				<tr>
					<th>saved_as</th>
					<td>string</td>
					<td>
						Name of the file that was saved
					</td>
				</tr>
				<tr>
					<th>error</th>
					<td>integer</td>
					<td>
						The error field will be updated after calling save() to indicate any errors encountered when trying to save the file.
					</td>
				</tr>
			</tbody>
		</table>

		<h3>Defined error constants</h3>

		<p>The Upload class defines the following error constants:</p>

		<table class="config">
			<tbody>
				<tr class="header">
					<th>Name</th>
					<th>Description</th>
				</tr>
				<tr>
					<th>UPLOAD_ERR_OK</th>
					<td>
						There is no error, the file uploaded with success.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_INI_SIZE</th>
					<td>
						The uploaded file exceeds the upload_max_filesize directive in php.ini.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_FORM_SIZE</th>
					<td>
						The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_PARTIAL</th>
					<td>
						The uploaded file was only partially uploaded.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_NO_FILE</th>
					<td>
						No file was uploaded. Note that entries with this error will be filtered when the uploaded file list is processed.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_NO_TMP_DIR</th>
					<td>
						Missing a temporary folder.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_CANT_WRITE</th>
					<td>
						Failed to write file to disk.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_EXTENSION</th>
					<td>
						A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_MAX_SIZE</th>
					<td>
						The file uploaded exceeds the maximum file size defined in the configuration.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_EXT_BLACKLISTED</th>
					<td>
						The extension of the file uploaded is defined in the extension blacklist.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_EXT_NOT_WHITELISTED</th>
					<td>
						The extension of the file uploaded is not defined in the extension whitelist.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_TYPE_BLACKLISTED</th>
					<td>
						The extension of the file uploaded is defined in the type blacklist.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_TYPE_NOT_WHITELISTED</th>
					<td>
						The extension of the file uploaded is not defined in the type whitelist.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_MIME_BLACKLISTED</th>
					<td>
						The extension of the file uploaded is defined in the mime-type blacklist.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_MIME_NOT_WHITELISTED</th>
					<td>
						The extension of the file uploaded is not defined in the mime-type whitelist.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_MAX_FILENAME_LENGTH</th>
					<td>
						The uploaded filename exceeds the defined maximum filename length.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_MOVE_FAILED</th>
					<td>
						The uploaded filename could not be moved from temporary storage to the path specified. This could mean that there's a permission issue.
					</td>
				</tr>
				<tr>
					<th>UPLOAD_ERR_DUPLICATE_FILE</th>
					<td>
						The uploaded filename could not be saved because a file with that name already exists.
					</td>
				</tr>
			</tbody>
		</table>

		<article>
			<h4>is_valid()</h4>
			<p>The <strong>is_valid</strong> can be used to check if there are any uploaded files present that have been validated.</p>
			<table class="method">
				<tbody>
				<tr>
					<th class="legend">Static</th>
					<td>Yes</td>
				</tr>
				<tr>
					<th>Parameters</th>
					<td>None</td>
				</tr>
				<tr>
					<th>Returns</th>
					<td>boolean - true if validated files exist, false if not.</td>
				</tr>
				<tr>
					<th>Example</th>
					<td>
						<pre class="php">
<code>// do we have any uploaded files to save?
if ( Upload::is_valid() )
{
	Upload::save();
}
</code></pre>
					</td>
				</tr>
				</tbody>
			</table>
		</article>

		<article>
			<h4>get_files($index = null)</h4>
			<p>The <strong>get_files</strong> method returns a multi-dimensional array with all files uploaded that have an error status = Upload::UPLOAD_ERR_OK.</p>
			<table class="method">
				<tbody>
				<tr>
					<th class="legend">Static</th>
					<td>Yes</td>
				</tr>
				<tr>
					<th>Parameters</th>
					<td>
						<table class="parameters">
							<tr>
								<th>Param</th>
								<th>Default</th>
								<th class="description">Description</th>
							</tr>
							<tr>
								<th><kbd>$index</kbd></th>
								<td><i>optional</i></td>
								<td>index number of the file in the uploaded files array. If not specified, or the index refers to a file with
								an error status other than UPLOAD_ERR_OK, an array with all validated files is returned.</td>
							</tr>
						</table>
					</td>
				</tr>
				<tr>
					<th>Returns</th>
					<td>array</td>
				</tr>
				<tr>
					<th>Example</th>
					<td>
						<pre class="php">
<code>// get the list of successfully uploaded files
foreach( Upload::get_files() as $file )
{
	// do something with the file info
}
</code></pre>
					</td>
				</tr>
				</tbody>
			</table>
		</article>

		<article>
			<h4>get_errors($index = null)</h4>
			<p>The <strong>get_files</strong> method returns a multi-dimensional array with all files uploaded that have an error status != Upload::UPLOAD_ERR_OK.</p>
			<table class="method">
				<tbody>
				<tr>
					<th class="legend">Static</th>
					<td>Yes</td>
				</tr>
				<tr>
					<th>Parameters</th>
					<td>
						<table class="parameters">
							<tr>
								<th>Param</th>
								<th>Default</th>
								<th class="description">Description</th>
							</tr>
							<tr>
								<th><kbd>$index</kbd></th>
								<td><i>optional</i></td>
								<td>index number of the file in the uploaded files array. If not specified, or the index refers to a file with
								an error status UPLOAD_ERR_OK, an array with all files in error is returned.</td>
							</tr>
						</table>
					</td>
				</tr>
				<tr>
					<th>Returns</th>
					<td>array</td>
				</tr>
				<tr>
					<th>Example</th>
					<td>
						<pre class="php">
<code>// get the list of uploaded files with errors
foreach( Upload::get_errors() as $file )
{
	// do something with the file info
}
</code></pre>
					</td>
				</tr>
				</tbody>
			</table>
		</article>

		<article>
			<h4>register($event, $callback)</h4>
			<p>
				The <strong>register</strong> method allows you to register callbacks for specific upload events,
				and allow you to add your own code to the <strong>process()</strong> and <strong>save()</strong> methods.
			</p>
			<table class="method">
				<tbody>
				<tr>
					<th class="legend">Static</th>
					<td>Yes</td>
				</tr>
				<tr>
					<th>Parameters</th>
					<td>
						<table class="parameters">
							<tr>
								<th>Param</th>
								<th>Default</th>
								<th class="description">Description</th>
							</tr>
							<tr>
								<th><kbd>$event</kbd></th>
								<td><i>required</i></td>
								<td>name of the callback event you want to register. Valid names are 'validate', 'before' and 'after'.</td>
							</tr>
							<tr>
								<th><kbd>$callback</kbd></th>
								<td><i>required</i></td>
								<td>Valid PHP callback function. This can be a function, a dynamic or static method, or a closure.</td>
							</tr>
						</table>
					</td>
				</tr>
				<tr>
					<th>Returns</th>
					<td>boolean - true if the callback was registered, false if the registration failed.</td>
				</tr>
				<tr>
					<th>Example</th>
					<td>
						<pre class="php">
<code>// register a before callback using a closure
Upload::register('before', function (&amp;$file) {
		if ($file['error'] == Upload::UPLOAD_ERR_OK)
		{
			switch($file['extension'])
			{
				case "jpg":
				case "png":
				case "gif":
					// store these in the images subdirectory
					$file['path'] .= 'images/';
				break;

				case "css":
					// store these in the css subdirectory
					$file['path'] .= 'css/';
				break;

				case "js":
					// store these in the javascript subdirectory
					$file['path'] .= 'js/';
				break;

				default:
					// don't modify the path for all others
			}
		}
	}
);
</code></pre>
					</td>
				</tr>
				</tbody>
			</table>
			<p>
				If you want to use a 'validate' callback, be sure to register it before you call Upload::process().
				If you have used the 'auto_process' configuration setting, Upload::process() will be called as soon as you use the Upload class,
				which means you will have to call it again after you have defined the callback.
			</p>
			<p>
				The callback will receive an entry from the uploaded files array as parameter. The entry is passed by reference, which allows
				the callback function to modify the entries of the array.<br />
				If the callback function returns an integer, it is assumed to be an update of the uploaded file's error code.
				All other return values are ignored.
			</p>
		</article>

		<article>
			<h4>process($config = array())</h4>
			<p>
				The <strong>process</strong> method processes the information about all uploaded files,
				normalizes the different permutations of form field names that can be used,
				fetches additional information about the file and its mimetype,
				and validates the file.
			</p>
			<table class="method">
				<tbody>
				<tr>
					<th class="legend">Static</th>
					<td>Yes</td>
				</tr>
				<tr>
					<th>Parameters</th>
					<td>
						<table class="parameters">
							<tr>
								<th>Param</th>
								<th>Default</th>
								<th class="description">Description</th>
							</tr>
							<tr>
								<th><kbd>$config</kbd></th>
								<td><i>optional</i></td>
								<td>array of configuration items, so you can override the settings defined in the configuration file.</td>
							</tr>
						</table>
					</td>
				</tr>
				<tr>
					<th>Returns</th>
					<td>void</td>
				</tr>
				<tr>
					<th>Example</th>
					<td>
						<pre class="php">
<code>// process the uploaded files
// set the max size to 10Kb, and allow overwrites of duplicate files
Upload::process( array('max_size' => 10240, 'auto_rename' => false, 'overwrite' => true) );
</code></pre>
					</td>
				</tr>
				</tbody>
			</table>
		</article>

		<article>
			<h4>save( ... )</h4>
			<p>The <strong>save</strong> method saves all validated files uploaded to the path specified.</p>
			<table class="method">
				<tbody>
				<tr>
					<th class="legend">Static</th>
					<td>Yes</td>
				</tr>
				<tr>
					<th>Parameters</th>
					<td>
						<table class="parameters">
							<tr>
								<th>Param</th>
								<th>Default</th>
								<th class="description">Description</th>
							</tr>
							<tr>
								<th><kbd>$integer</kbd></th>
								<td><i>optional</i></td>
								<td>Key of the files array returned by <strong>get_files()</strong>. This allows you so save an individual file from a set of uploaded files.</td>
							</tr>
							<tr>
								<th><kbd>$array</kbd></th>
								<td><i>optional</i></td>
								<td>Array of keys of the files array returned by <strong>get_files()</strong>. This allows you so save a selection of files from a set of uploaded files.</td>
							</tr>
							<tr>
								<th><kbd>$string</kbd></th>
								<td><i>optional</i></td>
								<td>The path the files should be saved to. This overrides the path specified in the configuration, or passed in the $config array when the <strong>process()</strong> method was called.</td>
							</tr>
						</table>
						<br />
						Note that the order in which these parameters are given is not relevant, and all of them are optional. But either use $integer or $array, and not both. If you do, the last one specified will be used.
					</td>
				</tr>
				<tr>
					<th>Returns</th>
					<td>void</td>
				</tr>
				<tr>
					<th>Example</th>
					<td>
						<pre class="php">
<code>// save all validated files
Upload::save();

// save only the first uploaded file
Upload::save( 1 );

// save all validated files, and to an alternate location
$arr = Upload::get_files();
Upload::save(DOCROOT.'assets', $arr );

// process any errors on these files
foreach ( Upload::get_errors() as $key => $file )
{
	// process the error code here
}
</code></pre>
					</td>
				</tr>
				</tbody>
			</table>
		</article>

	</section>

	<section id="footer">
		<p>
			<a href="http://fuelphp.com">Fuel</a> is released under the MIT license.<br />
			&copy; 2010 - 2011 Fuel Development Team
		</p>
	</section>

</body>
</html>
